﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.WebControls;
using ConsolidationTool.WebParts.ControlTemplates;
using ConsolidationTool.Common;
using System.Web.Script.Serialization;
using Microsoft.SharePoint;
using System.Web.UI.WebControls;

namespace ConsolidationTool.WebParts
{
    public class FSReportBase : LayoutsPageBase
    {
        public virtual CommonEntitySelector TopSelector { get; set; }
        public List<TemplateItem> TableTemplateItems { get; set; }
        public List<TemplateItem> ReportTemplateItems { get; set; }
        public List<TemplateItem> FreeRepeaterTemplateItems { get; set; }

        public SearchEntity CEntity { get; set; }
        public string EngMonth { get; set; }
        public string Year { get; set; }
        public string List { get; set; }

        public virtual string CacheType { get; set; }

        public bool isMerge { get { return !Request["merge"].IsNullOrEmpty(); } }
        public bool Automatic { get { return Request["automatic"] == "true"; } }
        public Dictionary<string, List<RQDataItem>> MainOutput = new Dictionary<string, List<RQDataItem>>();
        public Dictionary<string, string> AdditionOutput = new Dictionary<string, string>();

        public virtual Repeater BaseFreeRepeater { get; set; }
        public virtual Repeater BaseReport { get; set; }
        public virtual Repeater BaseGAP { get; set; }

        public virtual void Page_Load(object sender, EventArgs e)
        {
            BeforLoad();

            TopSelector.EntitySelectorChanged += new CommonEntitySelector.EntitySelectorChangeHandler(TopSelector_EntitySelectorChanged);

            if (BaseReport != null)
                BaseReport.ItemDataBound += new RepeaterItemEventHandler(RPGAP_ItemDataBound);
            if (BaseGAP != null)
                BaseGAP.ItemDataBound += new RepeaterItemEventHandler(RPGAP_ItemDataBound);
            if (BaseFreeRepeater != null)
                BaseFreeRepeater.ItemDataBound += new RepeaterItemEventHandler(RPGAP_ItemDataBound);

            if (!IsPostBack)
                CheckAutomaticReport();
        }
        #region Masterdata
        public Dictionary<string, string> RGC = new Dictionary<string, string>();
        public Dictionary<string, string> Region = new Dictionary<string, string>();
        public Dictionary<string, string> SubRegion = new Dictionary<string, string>();
        public Dictionary<string, string> Entity = new Dictionary<string, string>();


        public virtual void LoadMasterData()
        {
            if (CacheType.IsNotNullOrEmpty() && CacheType.IndexOf("RGC") != -1)
            {
                var list = SPContext.Current.Web.Lists["RGC"];
                if (list != null)
                {
                    var items = list.Items;
                    var itemCount = items.Count;
                    for (int i = 0; i < itemCount; i++)
                    {
                        var item = items[i];
                        var title = item["RGC"] + "";
                        if (!RGC.ContainsKey(title))
                            RGC.Add(title, item["Description"] + "");
                    }
                }
            }
            if (CacheType.IsNotNullOrEmpty() && CacheType.IndexOf("Entity") != -1)
            {
                var list = SPContext.Current.Web.Lists["Entity"];
                if (list != null)
                {
                    var items = list.Items;
                    var itemCount = items.Count;
                    for (int i = 0; i < itemCount; i++)
                    {
                        var item = items[i];
                        var title = item["ConsolidationTool_CoCd"] + "";
                        if (!Entity.ContainsKey(title))
                            Entity.Add(title, item["Title"] + "");
                    }
                }
            }
            if (CacheType.IsNotNullOrEmpty() && CacheType.IndexOf("SubRegion") != -1)
            {
                var list = SPContext.Current.Web.Lists["Entity"];
                if (list != null)
                {
                    var items = list.Items;
                    var itemCount = items.Count;
                    for (int i = 0; i < itemCount; i++)
                    {
                        var item = items[i];
                        var title = item["ConsolidationTool_SubRegion"] + "";
                        title = title.Split('#').Last();
                        if (!SubRegion.ContainsKey(title))
                            SubRegion.Add(title, item["ConsolidationTool_CoCd"] + "");
                        else
                            SubRegion[title] += (item["ConsolidationTool_CoCd"] + ",");
                    }
                }
            }

        }

        #endregion

        public virtual void BeforLoad()
        {
            LoadMasterData();
            int y = 0, m = 0;
            int.TryParse(TopSelector.yearTextBox.Text, out y); int.TryParse(TopSelector.monthTextBox.Text, out m);
            CEntity = new SearchEntity()
            {
                List = List,
                CompanyName = TopSelector.lbCompanyFullName.Text,
                Currency = TopSelector.lbCompanyCurrency.Text,
                Toannge = TopSelector.lbCompanyTonnage.Text,
                Entity = TopSelector.lbCoCd.Text,
                Year = y,
                Month = m
            };

            // BusinessService.UsageItems = new List<SPListItem>();

            DateTime selectData = DateTime.Now;
            if (DateTime.TryParse(string.Format("{0}-{1}-{2}", CEntity.Year, CEntity.Month, 1), out selectData))
                CEntity.SelectedDateTime = selectData;

            CEntity.EngMonth = EngMonth = BusinessService.GetEngMonth(CEntity.Month);
            this.Year = CEntity.Year + "";
            CEntity.EntityName = TopSelector.HFCompanyFullName.Value;

        }


        private void CheckAutomaticReport()
        {
            if (Automatic)
            {
                TopSelector.yearTextBox.Text = Request["year"];
                TopSelector.monthTextBox.Text = Request["month"];
                TopSelector.lbCoCd.Text = Request["cocd"];

                TopSelector.lbCompanyFullName.Text = Request["fullname"];
                TopSelector.HFCompanyFullName.Value = Request["hfullname"];

                TopSelector.lbCompanyCurrency.Text = Request["currency"];
                TopSelector.lbCompanyTonnage.Text = Request["tonnage"];
                BeforLoad();
                GenerateReport_Click("Actumatic Create Report", null);
            }
        }

        public virtual void GenerateReport_Click(object sender, EventArgs e)
        {
            TemplateLocator();

            // Page.ClientScript.RegisterStartupScript(this.GetType(), "shwotable", "<script>$(function(){$(\"table.commontable\").show();});</script>");
        }

        public virtual void ExportReport_Click(object sender, EventArgs e)
        {
            var ART_Table_DataSource = ViewState["ART_Table_DataSource"] as List<RQDataItem>;
            var ART_GAP_DataSource = ViewState["ART_GAP_DataSource"] as List<RQDataItem>;
            var ART_Free_DataSource = ViewState["ART_Free_DataSource"] as List<RQDataItem>;

            if (!string.IsNullOrEmpty(CEntity.TableRow))
                MainOutput.Add(CEntity.TableRow, ART_Table_DataSource);
            if (!string.IsNullOrEmpty(CEntity.GAPRow))
                MainOutput.Add(CEntity.GAPRow, ART_GAP_DataSource);
            if (!string.IsNullOrEmpty(CEntity.FreeRow))
                MainOutput.Add(CEntity.FreeRow, ART_Free_DataSource);

            BusinessService.ARTReportCreateExcel(CEntity, MainOutput, AdditionOutput);

            Page.ClientScript.RegisterStartupScript(this.GetType(), "Message", string.Format("<script>window.open('" + CEntity.ReportUrl + "');</script>"));
        }

        public virtual void RPGAP_ItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            var dataItem = e.Item.DataItem as RQDataItem;
            Repeater rep = e.Item.FindControl("RPValue") as Repeater;
            rep.DataSource = dataItem.values;
            rep.DataBind();
        }

        public virtual void TemplateLocator()
        {
            string ReportTemplate = GetReportTemplate();
            if (string.IsNullOrEmpty(ReportTemplate)) return;
            string localCurrency = CEntity.Currency;
            localCurrency = localCurrency.StartsWith("K") ? localCurrency.Substring(1) : localCurrency;

            var allTableTemplateItems = new JavaScriptSerializer().Deserialize<List<TemplateItem>>(ReportTemplate);
            allTableTemplateItems.ForEach(p =>
            {
                if (p.title != null)
                {
                    p.title = TitleFix(p.title);
                }
            });

            TableTemplateItems = allTableTemplateItems.Where(p => p.type == "Table").ToList();
            ReportTemplateItems = allTableTemplateItems.Where(p => p.type == "Report").ToList();
            FreeRepeaterTemplateItems = allTableTemplateItems.Where(p => p.type == "FreeFormat").ToList();

            DefaultControlLoad();

            ReportLoad();
        }
        public string TitleFix(string str)
        {
            return str.Replace("_Tonnage_", CEntity.Toannge).Replace("€", CEntity.LocalCurrency).Replace("_Currency_", CEntity.LocalCurrency).TrimEnd();
        }
        private void ReportLoad()
        {
            if (BaseReport != null)
            {
                var datasource = new List<RQDataItem>();
                TableTemplateItems.ForEach(p =>
                {
                    RQDataItem rdi = new RQDataItem();
                    rdi.title = p.title;
                    rdi.values = new List<string>();

                    if (!p.emptyRow)
                        ItemFieldSwitch(p.fields, rdi, p.list, p.equ);
                    else
                        rdi.emptyRow = true;

                    datasource.Add(rdi);
                });

                ViewState["ART_Table_DataSource"] = datasource;

                BaseReport.DataSource = datasource;
                BaseReport.DataBind();
            }

            if (BaseGAP != null)
            {
                var RQReportDataSource = new List<RQDataItem>();

                ReportTemplateItems.ForEach(p =>
                {

                    RQDataItem rdi = new RQDataItem();
                    rdi.title = p.title;

                    if (p.emptyRow)
                    {
                        rdi.values = new List<string>(p.fieldCount);
                        rdi.emptyRow = true;
                    }
                    if (p.titleRow)
                        rdi.values = BusinessService.GetReportTitle(CEntity, p.fieldCount);
                    if (p.M12)
                        rdi.values = Common.BusinessService.GetLast12MonthFieldValues(CEntity.Entity, CEntity.Year, CEntity.Month, p.list, p.equFields, p.equ, p.withCurrentMonth, p.avg, p.C12);
                    if (p.Budget)
                        rdi.values = Common.BusinessService.GetBudgetLast12MonthFieldValues(CEntity.Entity, CEntity.Year, CEntity.Month, p.list, p.equFields, p.equ, p.withCurrentMonth, p.compress, p.onlycm, p.otherExp);

                    RQReportDataSource.Add(rdi);

                });

                ViewState["ART_GAP_DataSource"] = RQReportDataSource;

                BaseGAP.DataSource = RQReportDataSource;
                BaseGAP.DataBind();
            }

            if (BaseFreeRepeater != null)
            {
                var FreeRepeaterDataSource = new List<RQDataItem>();
                FreeRepeaterTemplateItems.ForEach(p =>
                {
                    //Same with Base report
                    RQDataItem rdi = new RQDataItem();
                    rdi.title = p.title;
                    rdi.values = new List<string>();

                    if (!p.emptyRow)
                        ItemFieldSwitch(p.fields, rdi, p.list, p.equ);
                    else
                        rdi.emptyRow = true;

                    FreeRepeaterDataSource.Add(rdi);
                });

                ViewState["ART_Free_DataSource"] = FreeRepeaterDataSource;

                BaseFreeRepeater.DataSource = FreeRepeaterDataSource;
                BaseFreeRepeater.DataBind();
            }

        }

        public List<string> GetReportTitle(int c)
        {
            return BusinessService.GetReportTitle(CEntity, c);
        }

        public virtual void TopSelector_EntitySelectorChanged(object sender, int EntityID)
        {

        }


        //protected override void OnUnload(EventArgs e)
        //{
        //    BusinessService.UsageItems.Clear();
        //    base.OnUnload(e);
        //}

        public virtual void DefaultControlLoad()
        {
            var lbCM = this.Page.Controls.AllOfType<Label>().FirstOrDefault(p => p.ID == "lbCM");
            var lbYTD = this.Page.Controls.AllOfType<Label>().FirstOrDefault(p => p.ID == "lbYTD");
            var lbFSCurrencys = this.Page.Controls.AllOfType<Literal>().Where(p => !string.IsNullOrEmpty(p.ID) && p.ID.StartsWith("lbFSCurrency"));
            lbFSCurrencys.ToList().ForEach(p =>
            {
                p.Text = CEntity.Currency;
            });
            if (lbCM != null)
                lbCM.Text = CEntity.CM;
            if (lbYTD != null)
                lbYTD.Text = CEntity.YTDM;
        }


        public string GetReportTemplate()
        {
            string filepath = Server.MapPath(Request.Url.LocalPath).ToLower();
            filepath = filepath.Replace("brochure", "Brochure\\Template").Replace(".aspx", ".js");
            string temp = "";
            if (System.IO.File.Exists(filepath))
            {
                using (System.IO.StreamReader sr = new System.IO.StreamReader(filepath))
                {
                    temp = sr.ReadToEnd();
                }
            }
            return temp;
        }

        public void ItemFieldSwitch(List<TemplateItemField> list, RQDataItem rdi, string listName, string defaultEqu)
        {
            rdi.Max = "";
            list.ForEach(p =>
            {
                string result = string.Empty;
                string field = p.name;
                string invokeList = string.IsNullOrEmpty(p.list) ? listName : p.list;
                string methodFix = field;
                p.addition = string.IsNullOrEmpty(p.addition) ? defaultEqu : p.addition;

                if (!string.IsNullOrEmpty(p.type))
                {
                    field = p.type + "_" + p.name;
                    methodFix = p.self ? "Self" : field;

                    var method = this.GetType().GetMethod("Get" + methodFix + "Value");

                    if (p.self)
                        result = method.Invoke(this, new object[] { p, invokeList, rdi }) + "";
                    else
                        result = method.Invoke(this, new object[] { p, invokeList }) + "";

                    var pro = rdi.GetType().GetProperty(field);

                    if (pro != null)
                        pro.SetValue(rdi, result, null);
                }
                else if (p.emptycolumn)
                {
                    result = "";

                }
                else
                {
                    result = p.value;
                }

                rdi.values.Add(result);
            });
        }

        #region Utility

        public string CalcByTonnage(decimal p)
        {
            //if (CEntity.Toannge == "KG")
            //{
            //    return (p / 10000000).ToString("N3");
            //}
            //return (p / 1000).ToString("N3");
            return p.ToString("N3");
        }

        #endregion

        #region Members

        public string GetM_N_1Value(TemplateItemField f, string list)
        {
            return GetMField(f, (CEntity.Year - 1), list);
        }

        public string GetM_ActualValue(TemplateItemField f, string list)
        {
            return GetMField(f, CEntity.Year, list);
        }

        public string GetMField(TemplateItemField f, int year, string list)
        {
            SPListItem item = BusinessService.GetListItem(CEntity.Entity, year, CEntity.Month, list);

            return BusinessService.ComplieCalc(f.fields, f.addition, item) + "";
        }

        public string GetM_BudgetValue(TemplateItemField f, string list)
        {
            return BusinessService.GetBudgetValue(list, CEntity.Entity, CEntity.Year, CEntity.Month, f.fields, f.addition) + "";
        }

        public string GetKO_MValue(TemplateItemField f, string list)
        {
            return GetMKOValue(new SearchEntity()
            {
                Month = CEntity.Month,
                Entity = CEntity.Entity,
                Year = CEntity.Year,
                fields = f.fields,
                equ = f.addition
            }, list);
        }

        public string GetKO_N_1Value(TemplateItemField f, string list)
        {
            return GetMKOValue(new SearchEntity()
            {
                Month = CEntity.Month,
                Entity = CEntity.Entity,
                Year = CEntity.Year - 1,
                fields = f.fields,
                equ = f.addition
            }, list);
        }

        public string GetMKOValue(SearchEntity ce, string list)
        {
            SPListItem item = BusinessService.GetListItem(ce.Entity, ce.Year, ce.Month, list);
            if (item == null) return "";

            var listData = BusinessService.RefJsonData<koOutputEntity>(item["BillData"] + "");
            return BusinessService.GetBudgetFieldValueByMonth(ce, listData).ToString();
        }

        public string GetKO_YTDValue(TemplateItemField f, string list)
        {
            return BusinessService.GetKoTypeFieldYTDValue(new SearchEntity() { YTD = true, Budget = false, Month = CEntity.Month, Entity = CEntity.Entity, Year = CEntity.Year, fields = f.fields, equ = f.addition, List = list }).ToString("N0");
        }

        public string GetYTD_N_1Value(TemplateItemField f, string list)
        {
            int year = (CEntity.Year - 1);

            return GetYTDValue(f, year, CEntity.Month, list);
        }

        public string GetYTD_ActualValue(TemplateItemField f, string list)
        {
            return GetYTDValue(f, CEntity.Year, CEntity.Month, list);
        }

        public string GetYTD_BudgetValue(TemplateItemField f, string list)
        {
            var item = BusinessService.GetListItem(CEntity.Entity, CEntity.Year, list);
            return BusinessService.GetBudgetYTDValue(new SearchEntity()
            {
                Month = CEntity.Month,
                Entity = CEntity.Entity,
                Year = CEntity.Year,
                fields = f.fields,
                YTD = true,
                equ = f.addition
            }, item) + "";
        }

        public string GetSelfValue(TemplateItemField f, string list, RQDataItem rdi)
        {

            string express = f.addition;

            if (string.IsNullOrEmpty(express))
            {
                return BusinessService.GetObjectValue(rdi, f.type + "_" + f.fields[0]) + "";
            }
            else
            {
                for (int i = 0; i < f.fields.Length; i++)
                {
                    decimal temp = 0;
                    temp = BusinessService.GetObjectValue(rdi, f.type + "_" + f.fields[i]);

                    if (!string.IsNullOrEmpty(express))
                    {
                        express = express.Replace("{" + i + "}", temp + "");
                    }
                }
            }

            string error = "";
            express = BusinessService.GetDivision(express);
            return Evaluator.Eval(express, out error);
        }

        public string GetYTDValue(TemplateItemField f, int year, int month, string list)
        {
            decimal temp = 0;
            try
            {
                string express = f.addition;

                if (string.IsNullOrEmpty(express))
                {
                    temp += GetScopeMonthField(f.fields[0], year, month, list);
                }
                else
                {
                    for (int a = 0; a < f.fields.Length; a++)
                    {
                        decimal v = 0;
                        v = GetScopeMonthField(f.fields[a], year, month, list);

                        if (!string.IsNullOrEmpty(express))
                        {
                            express = express.Replace("{" + a + "}", v + "");
                        }
                    }
                    string error = "";
                    express = BusinessService.GetDivision(express);
                    string t = Evaluator.Eval(express, out error);
                    if (!error.IsNullOrEmpty())
                    {
                        Utilities.Log(error);
                        t = "0";
                    }

                    temp += decimal.Parse(t);
                }


            }
            catch (Exception ex)
            {
                Utilities.Log("FSReportBase-477 " + ex.Message);
            }
            return temp + "";
        }

        public decimal GetScopeMonthField(string field, int year, int month, string list)
        {
            decimal temp = 0;

            for (int i = 1; i <= month; i++)
            {
                if (field.IndexOf("|") != -1)
                {
                    list = field.Split('|')[0];
                    field = field.Split('|')[1];
                }
                SPListItem item = BusinessService.GetListItem(CEntity.Entity, year, i, list);
                temp += BusinessService.decimalParse(BusinessService.GetFieldValue(item, field));
            }

            return temp;
        }

        #endregion
    }
}
